#ifndef __AW_ThreadedBrain
#define __AW_ThreadedBrain

class AW_ThreadedBrain : public AW_TracerBrain {
	
public:
	AW_ThreadedBrain(Ontology *O,FTKBase *Memory,bool pause);
	AW_ThreadedBrain(FILE *fp,Ontology *O,FTKBase *Memory,bool pause);

	~AW_ThreadedBrain(); 

	virtual bool load(FILE *fp);
	virtual bool save(FILE *fp);

	virtual bool is_a(char *c);
	virtual bool is_a(Symbol *c);

	static void *launch_thread(void *brain);
	virtual void thread(void);

	virtual void pause(void);
	virtual void unpause(void);

	virtual void actualize(float time,float timeinc,
					       List<AW_Message> *message_queue,
						   Symbol *me,
						   List<FeatureTerm> *sensor_data,
						   List<FeatureTerm> *posibles,
						   List<FeatureTerm> *l);

protected:
	virtual void decode_input(float time,float timeinc,
							  Symbol *me,
							  List<FeatureTerm> *sensor_data,
							  List<FeatureTerm> *posibles,
							  List<FeatureTerm> *input_ops);
	virtual bool process_message(AW_Message *m,
								 float time,float timeinc,
							     Symbol *me,
							     List<FeatureTerm> *sensor_data,
							     List<FeatureTerm> *posibles,
							     List<FeatureTerm> *input_ops);

	void enqueue_operator(FeatureTerm *op);
	FeatureTerm *dequeue_operator(void);

	bool pending_messages_p(void);	/* checks whether there are incomming messages */ 
	void wait_message(void);		/* waits till a new message arrives */ 
	AW_Message *get_message(void);
	void wait(unsigned int milisec);		/* This function waits 'milisec' miliseconds, and during the wait checks whether the thread */ 
								/* has to be cancelled. This function is intended to be used inside the 'thread' function */ 
	void test_status(void);		/* This function should be called periodically in the 'thread' function */ 

	/* Sensor data: */ 
	pthread_mutex_t m_sensor_data_mutex; 
	List<FeatureTerm> m_sensor_data;

private:
	pthread_t m_thread;
	pthread_attr_t m_thread_attr;

	/* Queue of operators that the brain is asking to do: */ 
	pthread_mutex_t m_ops_queue_mutex; 
	List<FeatureTerm> m_ops_queue;

	/* These variables control the pause/continue states of the thread: */ 
	bool m_pause;
	pthread_mutex_t m_pause_mutex; 
	pthread_cond_t m_pause_cond; 

	/* Message queue: */ 
	pthread_mutex_t m_message_queue_mutex; 
	List<AW_Message> m_message_queue;

}; /* AW_ThreadedBrain */ 

#endif




